package com.yzl.frelink.service.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.yzl.frelink.entities.Fretish;
import com.yzl.frelink.entities.dep.Demap;
import com.yzl.frelink.service.AnalyzerService;
import com.yzl.frelink.util.CsvReader;
import com.yzl.frelink.util.JsonReader;

@Service
public class AnalyzerServiceImpl implements AnalyzerService {
    @Value("${frelink.withEnter}")
    private boolean withEnter;
    @Override
    public void greeting() {
        System.out.println("Hello, World!");
    }

    @Override
    public Fretish[] input(String filePath) {
        try{
            if (filePath.endsWith(".json")) {
                return inputFromJson(filePath);
            } else if (filePath.endsWith(".txt")) {
                return inputFromTxt(filePath);
            } else if (filePath.endsWith(".csv")) {
                return inputFromCsv(filePath);
            }
        } catch (Exception e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
        return new Fretish[0];
    }

    private Fretish[] inputFromJson(String filePath) throws Exception {
        Fretish[] requirements = JsonReader.parseFromFile(filePath);
        return requirements;
    }

    private Fretish[] inputFromTxt(String filePath) throws Exception {
        // TODO: Implement TXT file parsing
        System.out.println("TXT file parsing not implemented yet.");
        return new Fretish[0];
    }

    private Fretish[] inputFromCsv(String filePath) throws Exception {
        Fretish[] requirements = CsvReader.readCsv(filePath);
        return requirements;
    }

    @Override
    public Demap getDependency(Fretish[] requirements) {
        Demap demap = new Demap();

        // 提取状态
        String preMode = "preBool\\s*\\(\\s*(([a-zA-Z]|[0-9]|_)*)\\s*,\\s*[^\\)]*\\)";
        String postMode = "\\(([^\\)]*)\\)";
        String enterMode = "enter_([^\\)]*)";
        for (Fretish req : requirements) {
            // scope中的mode为状态
            if (req.getScope() != null && !req.getScope().isEmpty()) {
               demap.addMode(req.getScope());
            }
            if (withEnter) {
                // response中的enter_XXX为状态
                String response = req.getResponse();
                Matcher enterMatcher = Pattern.compile(enterMode).matcher(response);
                if (enterMatcher.find()) {
                    String var = enterMatcher.group(1).trim();
                    demap.addMode(var);
                }
            }

            // when preBool() 中的第一个参数为状态，且同时response设置变量也为状态
            if (req.getCondition() != null && !req.getCondition().isEmpty()) {
                String cond = req.getCondition();
                Matcher preMatcher = Pattern.compile(preMode).matcher(cond);
                if (preMatcher.find()) {
                    String var = preMatcher.group(1);
                    demap.addMode(var);
                    if (req.getOutVars().size() == 1) {
                        String outMode = req.getOutVars().get(0).replace("enter_", "").trim();
                        demap.addMode(outMode);
                    }
                //     String response = req.getResponse();
                //     Matcher postMatcher = Pattern.compile(postMode).matcher(response);
                //     if (postMatcher.find()) {
                //          var = postMatcher.group(1);
                //         demap.addMode(var);
                //     }
                }
            }
            // 添加规约
            demap.addReq(req.getReqid());
            // 添加变量
            for (String var : req.getVariables()) {
                if (withEnter && var.startsWith("enter_")) {
                    var = var.replace("enter_", "");
                }
                if (var.startsWith("send_")) {
                    var = var.replace("send_", "");
                }
                if (var.startsWith("receive_")) {
                    var = var.replace("receive_", "");
                }
                demap.addVar(var);
            }
            // 添加变量-规约依赖
            for (String inVar : req.getInVars()) {
                if (withEnter && inVar.startsWith("enter_")) {
                    inVar = inVar.replace("enter_", "");
                }
                if (inVar.startsWith("send_")) {
                    inVar = inVar.replace("send_", "");
                }
                if (inVar.startsWith("receive_")) {
                    inVar = inVar.replace("receive_", "");
                }
                demap.addEdge(inVar, req.getReqid());
            }
            // 添加规约-变量依赖
            for (String outVar : req.getOutVars()) {
                if (withEnter && outVar.startsWith("enter_")) {
                    outVar = outVar.replace("enter_", "");
                }
                if (outVar.startsWith("send_")) {
                    outVar = outVar.replace("send_", "");
                }
                if (outVar.startsWith("receive_")) {
                    outVar = outVar.replace("receive_", "");
                }
                demap.addEdge(req.getReqid(), outVar);
            }
        }
        // System.out.println("Demap: " + demap);
        return demap;
    }

    @Override
    public Map<String, List<Fretish>> groupByComponent(Fretish[] requirements) {
        Map<String, List<Fretish>> compToReqs = new HashMap<>();
        for (Fretish req : requirements) {
            String comp = req.getComponent();
            if (!compToReqs.containsKey(comp)) {
                compToReqs.put(comp, new ArrayList<>());
            }
            compToReqs.get(comp).add(req);
        }
        return compToReqs;
    }
}